﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
//#include <string.h>

#include "common.h"

int n1 = 1; // 全局变量声明
int m1 = 2;
extern int num_n; // 声明外部变量

int main()
{
	// if 语句测试部分
	{
		print_start_line("if 语句测试部分开始");
		int a1 = 0;
		if (a1 = 3) { // if 接多条语句的时候需要用大括号包裹
			printf("a被赋值了\n"); // 表达式的运算结果为 3 即非零，所以语句执行
			printf("表达式计算结果为3，即是a1的值，为%d\n", a1);
		}
		//if 语句实现分数等级判定
		float gared = 0.0; // 初始化
		//printf("请输入一个成绩：");
		//scanf("%f", &gared); // 这里不能用 a1 因为其已经被赋值过一次（除了初始化）
		gared = -10;
		if (gared < 0 || gared > 100) printf("成绩输入错误\n"); // 代码书写不规范
		else if (gared < 60) printf("成绩不合格\n");
		else if (gared >= 60 && gared < 70) printf("成绩合格\n");
		else if (gared >= 70 && gared < 80) printf("成绩中等\n");
		else if (gared >= 80 && gared < 90) printf("成绩良好\n");
		else if (gared >= 80 && gared <= 100) printf("成绩优秀\n");
		// 上一行可直接用 else

		// 注意：设 age = 10 表达式为 18 <= age < 28 的计算方式为 18<=10 结果为 0，
		// 0 < 28 结果为 1 所以语句会被输出
		int age = 10;
		if (18 <= age < 28) printf("年龄是青年\n"); // 语句被输出了

		// 注意，分号表示一条语句结束（重要），除非有大括号包裹，
		// else 不写大括号包裹代码块，默认只控制一条语句
		age = -5;
		if (age < 0) printf("查无此人\n");
		else
			printf("有实际年龄\n");
		printf("谁便打打字\n"); // 语句被执行
	}

	// 以下代码什么也不打印，
	// 因为第一个 if 成立了才会进入语句，下面的 else 链接（绑定）到第二个 if 
	// 所以 else 属于第二个 if 的代码块，不会被执行
	// 重要：else 总是与前面最近一个 if 匹配
	int num1 = 0;
	int num2 = 2;
	if (num1 == 1)    // 注意这里没有分号，推荐写法 if (1 == num1) 把数字写左边
		if (num2 == 2)
			printf("num2值为2成立\n");
		else // 这里的 else 属于第二个 if 的代码块，不会被执行
			printf("num1值不为1\n");

	// if 语句测试部分
	{
		// 调用判断奇数函数
		//odd_scanf();
		// 调用输出1~100之间的奇数的函数
		odd_zero_to_one_hundred();
		print_end_line("if 语句测试部分结束");
	}

	// switch 语句测试部分
	{
		print_start_line("switch 语句测试部分开始");
		// 判断星期日期
		week_day(num2); // 星期二
		week_day_state(6);
		week_day_state(num2);
		// 测试 switch 嵌套
		printf("num_n的值为：%d\n", num_n);
		switch_in_switch(n1, m1); // 传入的形式参数n的值为3，形式参数m的值为5
		printf("n1的值为%d，m1的值为%d\n", n1, m1);
		printf("num_n的值变为：%d\n", num_n);
		print_end_line("switch 语句测试部分结束");
	}

	// 测试 while 循环语句部分
	{
		print_start_line("while 循环语句部分开始");
		// 调用测试 while 循环函数
		int num_test_while = 0;
		test_while(num_test_while);
		printf("\n");

		// 调用打印按键字符和对应 ASCII 码的函数
		//char_test();  // 死循环

		// 调用输入密码测试函数
		//password_input_test();

		// 调用只打印数字的函数
		//only_output_num();
		print_end_line("while 循环语句部分结束");
	}

	//for 循环部分
	{
		print_start_line("for 循环语句部分开始");
		for_test(10);
		printf("\n");
		printf_num();
		for_more();
		print_end_line("for 循环语句部分结束");
	}

	// do ... while 部分
	{
		print_start_line("do ... while 部分开始");
		do_while_test();
		printf("\n");
		print_end_line("do ... while 部分结束");
	}

	// goto 语句学习部分
	{
		print_start_line("goto 语句学习部分开始");
		goto_test();
		//shutdown_test();
		print_end_line("goto 语句学习部分结束");
	}

	// 题目练习部分
	{
		print_start_line("题目练习部分开始");
		//date_output();
		//grade_output();
		//max_four(4);
		printf("%d\n", n_factorial(6)); // 数字过大导致溢出会使得结果为 0
		int sum_factorial = 0, ten_sum = 0; // 多个整型同时初始化写法
		while (sum_factorial < 10)
		{ // 在函数的基础上计算 1！+ 2！+ 3！+ ... + 10!
			sum_factorial++;
			ten_sum += n_factorial(sum_factorial);
		}
		printf("1到10的阶乘的和为：%d\n", ten_sum);
		// 嵌套循环实现
		int a10 = 1, ret = 0, n10 = 1, sum10 = 0;
		for (a10 = 1; a10 <= 10; a10++)
		{
			ret = 1;
			for (n10 = 1; n10 <= a10; n10++)
				ret *= n10;
			sum10 += ret;
		}
		printf("1到10的阶乘的和为(嵌套循环)：%d\n", sum10);

		// 二分查找法-循环实现
		{
			int search = 3;
			int arr_sort[10] = { 0,1,2,3,4,5,6,7,8,9 };
			int len_sort = sizeof(arr_sort) / sizeof(arr_sort[0]);
			int center = len_sort / 2;
			while (search != arr_sort[center])
			{ // 实现方式一
				if (search < center)
				{
					center /= 2; // 整除，如 7/2 = 3
					if (0 == center && search != arr_sort[center])
						break;
				}
				else
				{
					center = (len_sort + center) / 2;
					if (len_sort - 1 == center && search != arr_sort[center])
						break;
				}
			}
			if (search == arr_sort[center])
				printf("找到值%d，下标为：%d\n", search, center);
			else
				printf("没有找到值%d\n", search);
			// 实现方式二：
			int left = 0;
			int right = len_sort - 1;  // 下标
			while (left <= right)
			{
				//int mid = (left + right) / 2;   // mid 的优化：
				int mid = left + (right - left) / 2;
				/*printf("mid值为%d\n", mid);
				printf("arr_sort[mid]值为%d\n", arr_sort[mid]);*/
				if (arr_sort[mid] == search)
				{
					printf("找到值%d，下标为：%d\n", search, mid);
					break;
				}
				else if (search > arr_sort[mid])
					left = mid + 1;
				else if (search < arr_sort[mid])
					right = mid - 1;
			}
			if (left > right)
				printf("没有找到值%d\n", search);
		}

		// 代码实现从两端开始打印向中间汇聚
		printf_merge();

		// 模拟输入三次秘密输入，成功提示成功，错误则退出(密码：萝莉控)
		/*char atr[] = "sb";  // 注意字符串的定义必须用数组
		char btr[] = "sb";
		printf("%d\n", strcmp(atr, btr));*/
		//log_in("萝莉控", 3);

		// 做一个猜数字的小程序
		//guess_game();

		// 写代码实现将一个数组的数从大到小输出
		// 这里使用冒泡排序
		int arr_sort_test[10] = { 0,55,2,3,44,22,6,71,8,9 };
		int len_sort_test =
			sizeof(arr_sort_test) / sizeof(arr_sort_test[0]);
		bubble_sort(arr_sort_test, len_sort_test);

		// 求两数的最大公约数
		printf("(60,330)最大公约数为：%d\n", common_divisor(60, 330));

		// 数 1 到 1000 的所有整数中出现过多少次 9
		printf("1到1000的整数中出现过多少次9：%d\n", count_9(0, 1000, 9));
		// 计算 1/1 + 1/2 + 1/3 + ... + 1/1000 的值
		printf("1/1 - 1/2 + 1/3 - 1/4 + ... - 1/1000 的值：%f\n",
			sum_n_to_one(100));

		print_end_line("题目练习部分结束");
	}

	return 0;
}